package com.example.mybatis_plus_use.config;

import com.example.mybatis_plus_use.filter.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    //security过滤器可以配置多个，这里只配置一个且能够进行注入
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 1. 配置请求授权
                .authorizeHttpRequests(auth -> auth
                        // 白名单路径 先定义哪些路径需要认证，哪些路径不需要认证
                        .requestMatchers(
//                                "/user/login",      // 登录接口
//                                "/user/register",   // 注册接口 目前开发阶段先不开放注册接口
                                "/user/**",  // 允许所有用户访问
                                "/orders/**",  // 允许所有订单访问
                                "/category/**",  // 允许所有分类访问
                                "/article/**",  // 允许所有 Article 访问
                                "/user/GetAllUser", // 获取所有用户
                                "/swagger-ui/**",   //  Swagger UI 相关接口
                                "/v3/api-docs/**",  // OpenAPI文档
                                "/doc.html"  ,          // Swagger 文档的主页面
                                "/webjars/**",        // Swagger UI 所需的静态资源
                                "/swagger-resources/**" // Swagger资源文件
                        ).permitAll()
                        // 其他所有请求需要认证
                        .anyRequest().authenticated()//检查 SecurityContextHolder 中是否存在认证信息
                )//以上是最后的执行顺序配置，下面是添加JWT过滤器和禁用CSRF的配置
                //JWT过滤器处理token认证
                //UsernamePasswordAuthenticationFilter处理表单登录
                // 2. 添加JWT过滤器 再配置认证方式（JWT）
                .addFilterBefore(jwtAuthenticationFilter,  // 注意顺序，先执行JWT过滤器，
                        UsernamePasswordAuthenticationFilter.class)  // 再执行表单登录过滤器
                // 3. 禁用CSRF（因为使用JWT，不需要CSRF） （Spring Security内置的过滤器）
                //如果是login登陆接口则跳过jwt认证，直接返回token，执行表单登录
                //如果是其他接口则需要jwt认证，执行JWT过滤器，跳过表单登录
                //最后的认证检查（跳过）
                //      - 因为/login在permitAll列表中

                .csrf(csrf -> csrf.disable())
                // 4. 使用无状态会话（JWT不需要session）
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                );

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}